﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Huirui.Cavan.Domain.Seedwork;
using Huirui.Cavan.Domain.MainBoundedContext.SearchModule;
using Huirui.Cavan.Application.Seedwork;
using Huirui.Cavan.Domain.MainBoundedContext.StockModule;
using Huirui.Cavan.Application.MainBoundedContext.SystemModule;
using Spring.Context.Support;
using Huirui.Cavan.Core.Extension;
using Huirui.Cavan.Domain.MainBoundedContext.SystemModule;
using Huirui.Cavan.Domain.MainBoundedContext.PurchaseModule;
using Huirui.Cavan.Application.MainBoundedContext.PurchaseModule;
using Huirui.Cavan.Domain.MainBoundedContext.ReportModule;

namespace Huirui.Cavan.Application.MainBoundedContext.StockModule
{
    public class StockInOutAppService : BaseAppService<StockInOut, string, StockInOutSearch, IStockInOutRepository>, IStockInOutAppService
    {
        private IPurchaseOrderAppService PurchaseOrderAppService { get; set; }
        private IStockInOutTypeAppService StockInOutTypeAppService { get; set; }
        private IUnPayAppService UnPayAppService { get; set; }
        private IPurchaseAppService PurchaseAppService { get; set; }
        private IStockAppService StockAppService { get; set; }
        private IWareHouseAppService WareHouseAppService { get; set; }
        private ISupplierAppService SupplierAppService { get; set; }
        private IAccountAppService AccountAppService { get; set; }

        private Employee _employee;
        private StockManager _stockManager;

        public StockInOutAppService()
        {
        }

        #region IStockInAppService Members

        public override BoolGenericResult<StockInOut> AddOrUpdate(StockInOut entity)
        {
            Init();
            this.WareHouseAppService = this.SpringContext.GetObject(StockModuleConst.WAREHOUSEAPPSERVICE) as IWareHouseAppService;
            this.SupplierAppService = this.SpringContext.GetObject(SystemModuleConst.SUPPLIERAPPSERVICE) as ISupplierAppService;
            this.AccountAppService = this.SpringContext.GetObject(SystemModuleConst.ACCOUNTAPPSERVICE) as IAccountAppService;
            this.StockAppService = this.SpringContext.GetObject(StockModuleConst.STOCKAPPSERVICE) as IStockAppService;
            this.StockInOutTypeAppService = this.SpringContext.GetObject(StockModuleConst.STOCKINOUTTYPEAPPSERVICE) as IStockInOutTypeAppService;
            BoolGenericResult<StockInOut> result = new BoolGenericResult<StockInOut>();
            if (entity.IsNull())
            {
                throw new ArgumentNullException("");
            }

            StockInOut oldStockIn = null;
            if (entity.Id.IsNotEmpty())
            {
                oldStockIn = this.Repository.Get(entity.Id);
            }
            if (entity.WareHouse.IsNotNull() && entity.WareHouse.Id.IsNotEmpty())
            {
                entity.WareHouse = this.WareHouseAppService.GetById(entity.WareHouse.Id);
            }
            if (entity.Supplier.IsNotNull() && entity.Supplier.Id.IsNotEmpty())
            {
                entity.Supplier = this.SupplierAppService.GetById(entity.Supplier.Id);
            }
            if (entity.FromAccount.IsNotNull() && entity.FromAccount.Id.IsNotEmpty())
            {
                entity.FromAccount = this.AccountAppService.GetById(entity.FromAccount.Id);
            }
            if (entity.Type.IsNotNull())
            {
                entity.Type = this.StockInOutTypeAppService.GetById(entity.Type.Id);
            }
            foreach (StockInOutDetail siod in entity.StockInOutDetails)
            {
                siod.Stock = this.StockAppService.GetById(siod.Stock.Id);
                siod.WareHouse = entity.WareHouse;
            }

            _employee = this.EmployeeAppService.GetBySearch(SearchFactory.CreateEmployeeSearch(SecurityAppService.UserAccount.Id)).FirstOrDefault();
            _stockManager = new StockManager(_employee);

            if (entity.Employee.IsNotNull() && entity.Employee.Id.IsNotEmpty())
            {
                entity.Employee = this.EmployeeAppService.GetById(entity.Employee.Id);
            }
            else
            {
                entity.Employee = _employee;
            }

            if (oldStockIn.IsNull())
            {
                IIDGenerateAppService idGenerateAppService = this.SpringContext.GetObject(SystemModuleConst.IDGENERATEAPPSERVICE, new object[] { _employee.Corporation }) as IIDGenerateAppService;
                if (entity.Type.IsIn)
                {
                    entity.Id = idGenerateAppService.GenerateID(SystemIdentifier.ReceiptCodeRuleType.StockIn);
                    result = _stockManager.AddStockIn(entity.Id, entity.InOutDate, entity.Type, entity.SourceCode, entity.FromAccount, entity.ProductionNumber, entity.Currency, entity.CurrencyRate,
                        entity.Remark, entity.Contact, entity.ContactTelephone, entity.Department, entity.Employee, entity.Project, entity.Supplier, entity.Customer, entity.WareHouse, entity.StockInOutDetails);

                }
                else
                {
                    entity.Id = idGenerateAppService.GenerateID(SystemIdentifier.ReceiptCodeRuleType.StockOut);
                    result = _stockManager.AddStockOut(entity.Id, entity.InOutDate, entity.Type, entity.SourceCode, entity.FromAccount, entity.ProductionNumber, entity.Currency,
                        entity.CurrencyRate, entity.Remark, entity.Contact, entity.ContactTelephone, entity.Department, entity.Employee, entity.Project, entity.Supplier, entity.Customer,
                        entity.WareHouse, entity.StockInOutDetails);
                }
                if (result.IsSuccess)
                { 
                    base.Add(result.Object);
                    foreach (StockInOutDetail siod in entity.StockInOutDetails)
                    {
                       this.StockAppService.Update(siod.Stock);
                    }
                } 
            }
            else
            {
                result = _stockManager.UpdateStockIn(oldStockIn, entity.InOutDate, entity.Type, entity.FromAccount, entity.ProductionNumber,
                    entity.Remark, entity.Contact, entity.ContactTelephone, entity.Department, entity.Employee, entity.Project, entity.Supplier, entity.WareHouse, entity.StockInOutDetails);
                if (result.IsSuccess)
                    return base.Update(result.Object);
            }
            result.Messages.Add("保存成功");
            return result;
        }

        public IList<StockInOutReport> GetStockInReport(DateTime? startDate, DateTime? endDate, string supplierCode, string purchaseOrderCode, string wareHouseCode)
        {
            return this.Repository.GetStockInReport(startDate, endDate, supplierCode, purchaseOrderCode, wareHouseCode);
        }
        #endregion
    }
}
